﻿<template>
	<div class="project-container">
		<el-dialog v-model="isShowDialog" :width="1300" draggable="" @close="cancel" style="border-radius: 10px;">
			<template #header>
				<div style="color: #fff">
					<!--<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>-->
					<span>{{ props.title }}</span>
				</div>
			</template>
      <div style="margin-bottom: 20px">
			<el-form :model="ruleForm" ref="ruleFormRef" label-width="auto" :rules="rules">
				<el-row :gutter="35">
					<el-form-item v-show="false">
						<el-input v-model="ruleForm.id" />
					</el-form-item>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.projectNo')" prop="projectNo">
							<el-input v-model="ruleForm.projectNo"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.projectNo')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.projectName')" prop="projectName">
							<el-input v-model="ruleForm.projectName"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.projectName')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.customerCode')" prop="customerCode">
							<el-input v-model="ruleForm.customerCode"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.customerCode')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.customerName')" prop="customerName">
							<el-input v-model="ruleForm.customerName"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.customerName')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.comAddr')" prop="comAddr">
							<el-input v-model="ruleForm.comAddr"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.comAddr')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.comPhone')" prop="comPhone">
							<el-input v-model="ruleForm.comPhone"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.comPhone')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.contact')" prop="contact">
							<el-input v-model="ruleForm.contact"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.contact')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.cusAddr')" prop="cusAddr">
							<el-input v-model="ruleForm.cusAddr"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.cusAddr')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.cusPhone')" prop="cusPhone">
							<el-input v-model="ruleForm.cusPhone"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.cusPhone')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
						<el-form-item :label="$t('message.project.cusTel')" prop="cusTel">
							<el-input v-model="ruleForm.cusTel"
								:placeholder="$t('message.pageConfiguration.noticeinput') + ' ' + $t('message.project.cusTel')"
								maxlength="200" show-word-limit clearable />

						</el-form-item>

					</el-col>
        </el-row>
        <el-row justify="end">
          <el-col :span="4" style="text-align: right;">
            <el-button @click="cancel">{{ $t('message.pageConfiguration.cancel') }}</el-button>
            <el-button type="primary" @click="submit">{{ $t('message.pageConfiguration.confirm') }}</el-button>
          </el-col>
        </el-row>
        </el-form>
      </div>


  <div class="project-container">
       <el-card class="full-table" shadow="hover" style="margin-top: 0px">
      <Table ref="tableRef" v-bind="tb.tableData"  :getData="getData"  >

        <template #action="scope" >

          <el-button icon="ele-Edit" size="small" text="" type="primary" @click="getCAD(scope.row)"
            v-auth="'project:edit'"> Get CAD </el-button>
            <el-button icon="ele-Edit" size="small" text="" type="primary" @click="getpdf(scope.row.id)"
            v-auth="'project:edit'"> Get Quote </el-button>


        </template>
      </Table>

    </el-card>


</div>



            <div class="cards-container">
              <el-card
                  v-for="(card, index) in mapCards"
                  :key="index"
                  class="box-card">
                <div class="generation-info">
                  <span>Create time {{ card.generationTime || '2025-04-11 12:00:00' }}</span>
                  &nbsp;
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  <span> Serial #  {{ card.projectMapDetailId}}</span>
                  <el-button type="primary" size="small" style="float: right;" @click="downloadGridFile(card.gridBlob)">Download</el-button>
                </div>
                <div class="map-area">
                  <div class="map-background">
                    <img
                        :src="card.imageSrc"
                        alt="Map Layout"
                        class="map-image"
                        v-if="card.imageSrc"
                        crossorigin="anonymous"
                    />
                  </div>
                </div>
                 <div class="stats-info">
                  <el-row :gutter="5" style="width: 90% ;height: 25px;"> <!-- 设置列间距 -->
                    <el-col :span="5">
                      <span style="font-weight: bold">Area:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.totalBlocks }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>㎡</span>
                    </el-col>
                    <el-col :span="6">
                      <span style="font-weight: bold">AGV:</span>
                    </el-col>
                    <el-col :span="2">
                      <el-input @change="handelUpdate(card)"  class="custom-input" v-model="card.statsData.agv"  ></el-input>
                    </el-col>
                    <el-col :span="1" style="text-align: right;">
                      <el-icon><edit /></el-icon>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90% ;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Finger Qty:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.fingerCount }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                    <el-col :span="6">
                      <span style="font-weight: bold">Total Productivity:</span>
                    </el-col>
                    <el-col :span="2">
                      <el-input @change="handelUpdate(card)"  class="custom-input" v-model="card.statsData.totalProductCapacity "  ></el-input>
                    </el-col>
                    <el-col :span="1" style="text-align: right;">
                      <el-icon><edit /></el-icon>
                    </el-col>
                    <el-col :span="3">
                      <span>Piece/Hour</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90% ;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Chute:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.gridCount }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                    <el-col :span="6">
                      <span style="font-weight: bold">AGV Average Productivity:</span>
                    </el-col>
                    <el-col :span="2">
                      <el-input  @change="handelUpdate(card)" class="custom-input" v-model="card.statsData.singleProductCapacity"  ></el-input>
                    </el-col>
                    <el-col :span="1" style="text-align: right;">
                      <el-icon><edit /></el-icon>
                    </el-col>
                    <el-col :span="3">
                      <span>Piece/Hour</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90%;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Charger:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.chargingStations}}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90%;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Parking Lot:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.parkingSpaces }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90%;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Charging Lot:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.chargingParkingSpaces }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90%;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Queue:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.queueAreas }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90% ;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Common Area:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.operationAreas }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                  <el-row :gutter="5" style="width: 90% ;height: 25px;">
                    <el-col :span="5">
                      <span style="font-weight: bold">Infeed Station:</span>
                    </el-col>
                    <el-col :span="2">
                      <span>{{ card.statsData.dispatch_amount }}</span>
                    </el-col>
                    <el-col :span="3">
                      <span>Unit</span>
                    </el-col>
                  </el-row>
                </div>
                <div class="bottom-buttons">
                  <div class="bottom-buttons">
                    <!--              <el-button type="primary" size="small" @click="getADDCAD(card.gridBlob,card.projectMapDetailId)">Get CAD</el-button>-->
                    <el-button type="primary" size="small" @click="openAdjustParamsDialog(card.statsData,index,card.projectMapDetailId)">Adjust Map</el-button>
                    <el-button type="primary" size="small" @click="deleteMap(index,card.projectMapDetailId)">Delete Map</el-button>
                    <el-button type="primary" size="small" @click="getADDCAD(card.gridBlob,card.projectMapDetailId)">Get CAD</el-button>
                    <!--              <el-button type="primary" size="small" @click="generateDocument(card.projectMapDetailId)">Get PNG</el-button>-->
                     <el-button type="primary" size="small" @click="getpdf(card.projectMapDetailId)">Get Quote</el-button>
                  </div>
                </div>
              </el-card>
              <div class="upload-container" v-if="!isUploading">
                <input
                    type="file"
                    id="fileInput"
                    ref="fileInput"  style="display: none;"
                    @change="handleFileChange"
                />
                <div class="cross-icon" @click="startUpload"></div> <!-- 十字图标 -->
                <el-button type="primary" class="upload-button" @click="startUpload">Upload</el-button>
              </div>
            </div>
		</el-dialog>
    <AdjustParamsDialog ref="adjustParamsDialog" @update-image="handleUpdateImage" />
	</div>
</template>
<style scoped>
:deep(.el-select),
:deep(.el-input-number) {
	width: 100%;
}
</style>
<script lang="ts" setup>
import AdjustParamsDialog from './AdjustParamsDialog.vue';

import { onMounted, onUnmounted, reactive, ref, defineAsyncComponent, nextTick, watch,inject } from 'vue';
import {ElMessage, ElMessageBox} from "element-plus";
import type { FormRules } from "element-plus";
import {Edit, Plus} from "@element-plus/icons-vue";
import { UploadRequestOptions } from "element-plus";
import {getMapListByNo, updateProjectMap} from "/@/api/main/projectMap";
import {
  deleteProjectMapDetail,
  pageProject,
  addProject,
  detailProject,
  updateProject,
  sumDateMap, downloadProjectFile
} from "/@/api/main/project";
import {getpageProject, getProjectByNo,getAgvAverage} from "/@/api/main/projectQa";
import {
  generateTModel,
  generateScheme,
  editProjectMapDetailAsync,
  uploadCADFiles,
  addCADFiles,
  seleProjectMapDetail,
  updaagv

} from "/@/api/main/projectResult";

import { useI18n } from 'vue-i18n';
const { t, locale } = useI18n();

import JSZip from "jszip";

// 引入组件
const Table = defineAsyncComponent(() => import('/@/components/table/index.vue'));


// 注入父组件提供的刷新方法
const refreshParent = inject('refreshParent');

//表格刷新
const tableRef = ref<RefType>();
const agvCount = ref(0);


const isUploading = ref(false);
const formData = reactive({
  ID:undefined,
  Type: 1,
  SlotQty: 96,
  FingersQty: 2,
  HorizontalBarHeight: 10,
  FingerSpacing: 10,
  MinionsQty:0,
  TotalProductionCapacity:0,
  BicycleTotal:0,
  ParkingSpaceQty:  undefined,
  DispatchAmount: undefined
});
const fileInput = ref<HTMLInputElement | null>(null);
const adjustParamsDialog = ref();

//父级传递来的参数
var props = defineProps({
	title: {
		type: String,
		default: "",
	},
});
//父级传递来的函数，用于回调
const emit = defineEmits(["updateData"]);
const ruleFormRef = ref();
const isShowDialog = ref(false);
const ruleForm = ref<any>({});


//表格
const loading = ref();
const getData = async () => {

  loading.value = true;


  console.log('CC1');
  console.log(ruleForm.value.id);
  var res = await getpageProject(Object.assign(ruleForm.value.id));
  console.log(res.data);

  loading.value = false;
  //获取对应的图片   const { imageUrl, gridBlob } = await processZipFile(res.data[i].zipFile);
    console.log(res.data.result.length);
    for(let i = 0; res.data.result.length>i; i++){
//console.log(res.data.result[i].zipFile);res.data.result[i].push({ imageSrc: imageUrl });
const { imageUrl, gridBlob } = await processZipFile(res.data.result[i].zipFile);
res.data.result[i].imageSrc = imageUrl;
    }

    console.log(res.data);
  return res.data;
};
const tb = reactive<TableDemoState>
  ({
    tableData: {

      // 表头内容（必传，注意格式）
      columns: [
        { prop: 'id', width: 130, label: 'Serial #', headerAlign: 'left', toolTip: false, sortable: 'custom', isCheck: true ,align:'left'},
        { prop: 'minionsQty', width: 140, label: 'AGV Qty', headerAlign: 'left', toolTip: true, sortable: 'custom', isCheck: true,align:'left'  },
        { prop: 'totalProductionCapacity', width: 150, label: 'Total Productivity(P)', headerAlign: 'left', toolTip: true, sortable: 'custom', isCheck: true,align:'left' },
        { prop: 'bicycleTotal', width: 165, label: 'Average productivity(P)', headerAlign: 'left', toolTip: true, sortable: 'custom', isCheck: true,align:'left' },
        { prop: 'referPrice', width: 130, label: 'Estimated Quote', headerAlign: 'left', toolTip: true, sortable: 'custom', isCheck: true,align:'left' },


        { prop: 'occupyArea', width: 100, label: 'Area(㎡)', headerAlign: 'left', toolTip: true, sortable: 'custom', isCheck: true },
        { prop: 'imageSrc' , width: 80, label: 'Map layout', type: 'image', align: 'left', isCheck: true, fixed: 'right', hideCheck: true },
        { prop: 'action', width: 200, label: 'Action', type: 'action', align: 'left', isCheck: true, fixed: 'right', hideCheck: true },


      ],
      // 配置项（必传）
      config: {
        isStripe: false, // 是否显示表格斑马纹
        isBorder: false, // 是否显示表格边框
        isSerialNo: false, // 是否显示表格序号
        isSelection: false, // 是否勾选表格多选
        showSelection: false, //是否显示表格多选
        pageSize: 20, // 每页条数
        hideExport: false, //是否隐藏导出按钮
        exportFileName: 'project', //导出报表的文件名，不填写取应用名称
      },
      // 搜索表单，动态生成（传空数组时，将不显示搜索，type有3种类型：input,date,select）
      search: [


      ],
      param: {},
      defaultSort: {
        prop: 'createTime',
        order: 'ascending',
      },
    },
  });




const mapCards = ref<any[]>([])
const projectId = ref(undefined)


//自行添加其他规则
const rules = ref<FormRules>({
	projectNo: [{ required: true, message: t('message.pageConfiguration.noticeinput') + ' ' + t('message.project.projectNo'), trigger: 'blur', },],
	projectName: [{ required: true, message: t('message.pageConfiguration.noticeinput') + ' ' + t('message.project.projectName'), trigger: 'blur', },],
	customerCode: [{ required: true, message: t('message.pageConfiguration.noticeinput') + ' ' + t('message.project.customerCode'), trigger: 'blur', },],
	customerName: [{ required: true, message: t('message.pageConfiguration.noticeinput') + ' ' + t('message.project.customerName'), trigger: 'blur', },],
});

//获取图片
async function processZipFile(zipFileBase64: string) {
  const zip = new JSZip();
  await zip.loadAsync(zipFileBase64, { base64: true });
  // 提取图片文件（假设文件名为 "image.png"）
  const imageFile = zip.file('t-model.png');
  if (!imageFile) {
    throw new Error('Image file not found in ZIP');
  }
  const imageBlob = await imageFile.async('blob');
  const imageUrl = URL.createObjectURL(imageBlob);

  // 提取 grid 文件（假设文件名为 "grid.txt"）
  const gridFile = zip.file('test.grid');
  if (!gridFile) {
    throw new Error('Grid file not found in ZIP');
  }
  const gridBlob = await gridFile.async('blob');

  return { imageUrl, gridBlob };
}

// 打开弹窗
const openDialog = async (row: any) => {
  // 深拷贝 row 到 ruleForm.value
  ruleForm.value = JSON.parse(JSON.stringify(row));
  const imageUrl = ruleForm.value.cadFiles
  const projectNo = ruleForm.value.id;
  projectId.value  = projectNo;

  //获取产能并计算数据
  const qaDetail = await  getProjectByNo({ projectNo: projectId.value })
  const qa = qaDetail.data.result[0]
  agvCount.value = Math.round(qa.expectedThroughput / 50);

  const mapCardsArray = [];
  let res;
  try {
    res = await getMapListByNo({ projectNo: projectNo });
  } catch (error) {
    ElMessage.error('Retrieve map list error, please try later');
    console.error('getMapListByNo error:', error);
    return; // 停止后续执行
  }

  for (const item of res.data.result) {
    const { imageUrl, gridBlob } = await processZipFile(item.zipFile);
    console.log(imageUrl);
    console.log(gridBlob);
    console.log('kkk');

    mapCardsArray.push({
      imageSrc: imageUrl,
      gridBlob: gridBlob,
      projectMapDetailId: item.id,
      statsData: {
        totalBlocks: item.occupyArea,
        fingerCount: item.fingersQty,
        queueAreas: item.queueingAreaQty,
        operationAreas: item.operatingAreaQty,
        chargingStations: item.chargeStationQty,
        dispatch_amount: item.dispatchQty,
        chargingParkingSpaces: item.chargingParkingSpaceQty,
        parkingSpaces: item.parkingSpaceQty,
        gridCount: item.slotQty,
        generationMethod: 'Auto',
        agv: item.minionsQty,
        totalProductCapacity: item.totalProductionCapacity,
        singleProductCapacity: item.bicycleTotal,
        warehouseWidth:qa.warehouseWidth,
        warehouseLength:qa.warehouseLength,
        goodsWidth:qa.goodsWidth,
        goodsLength:qa.goodsWidth
      },
      generationTime: item.createTime
    });
  }
  mapCards.value = mapCardsArray;

  tableRef.value?.handleList(); // 刷新表格数据
  // 打开弹窗
  isShowDialog.value = true;
};

// 关闭弹窗
const closeDialog = () => {
	emit("updateData");
	isShowDialog.value = false;

};

// 取消
const cancel = () => {
	isShowDialog.value = false;
  refreshParent?.(); // 调用父组件刷新方法
};

// 提交
const submit = async () => {
	// let values = ruleForm.value;
	// if (ruleForm.value.id == undefined || ruleForm.value.id == null || ruleForm.value.id == "" || ruleForm.value.id == 0) {
	// 	await addProject(values);
	// } else {
	// 	await updateProject(values);
	// }

	// closeDialog();
	ruleFormRef.value.validate(async (isValid: boolean, fields?: any) => {
		if (isValid) {
			let values = ruleForm.value;
			if (ruleForm.value.id == undefined || ruleForm.value.id == null || ruleForm.value.id == "" || ruleForm.value.id == 0) {
				await addProject(values);
			} else {
				await updateProject(values);
			}
			// closeDialog();
			console.log(ruleForm.value.projectNo)
      ElMessage.success("Update completed");


			 console.log('ruleForm.value.projectNo:', ruleForm.value.projectNo);
  if (ruleForm.value.projectNo) {
		var projectno : string=ruleForm.value.projectNo.toString();
		console.log(projectno)
  // router.push({
  //     path: '/project/questioninfo',
  //     query: {
  //       ProjectNo: projectno
  //     }
  //   });

  } else {
    console.log('projectNo is null，page transfer error');
  }

		} else {
			ElMessage({
				message: `Validate sheet error in ${Object.keys(fields).length}，please change before stage`,
				type: "error",
			});
		}
	});
};

const handelUpdate = async (card: any) => {
  try {

    if(card.statsData.agv ==0||card.statsData.agv <0){
      card.statsData.singleProductCapacity = 0;


    }else {
    //计算AGV评价生产量
      //const qaDetail = await  getAgvAverage({ AGV:card.statsData.agv,totalProductCapacity:card.statsData.totalProductCapacity })
      const qaDetail = await getAgvAverage(
  card.statsData.agv,
  card.statsData.totalProductCapacity
);
 console.log(qaDetail.data.result);
            card.statsData.singleProductCapacity = qaDetail.data.result;
    }




    const { projectMapDetailId, statsData } = card;

    if (!projectMapDetailId) {
      await ElMessageBox.alert('Invalid Project ID', 'Warning', {
        confirmButtonText: 'Ok',
        type: 'warning'
      });




      return;
    }

    // 更新 formData
    formData.ID = projectMapDetailId;
    formData.Type = 1;
    formData.SlotQty = statsData.gridCount;
    formData.FingersQty = statsData.fingerCount;
    formData.MinionsQty = Number(statsData.agv);
    formData.TotalProductionCapacity = Number(statsData.totalProductCapacity);
    formData.BicycleTotal = Number(statsData.singleProductCapacity);
    formData.ParkingSpaceQty = statsData.parkingSpaces;
    formData.DispatchAmount = statsData.dispatch_amount;

    await editProjectMapDetailAsync(formData);

    await sumDateMap(projectMapDetailId,projectId.value)

    ElMessage.success("Update completed");
    console.log("formData updated:", formData);
    //刷新表格
    tableRef.value?.handleList(); // 刷新表格数据
  } catch (error) {
    ElMessage.error("Update error");
    console.error('Update project detail error:', error);
  }
};

//时间戳
function generateTimestamp() {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始
  const day = String(now.getDate()).padStart(2, '0');
  const hours = String(now.getHours()).padStart(2, '0');
  const minutes = String(now.getMinutes()).padStart(2, '0');
  const seconds = String(now.getSeconds()).padStart(2, '0');
  const milliseconds = String(now.getMilliseconds()).padStart(3, '0');

  return `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}`;
}





//下载地图文件
const downloadGridFile = (gridBlob: any) => {
  if (gridBlob) {
    const url = URL.createObjectURL(gridBlob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'test.grid';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  } else {
    console.error('No test.grid file available');
  }
}
// 打开调整参数弹窗
const openAdjustParamsDialog = (data:any,index:any,id:any) => {
  console.log('detail', data);
  const initialValues = {
    id: id,
    chuteAmount: Number(data.gridCount),
    fingerCount: Number(data.fingerCount),
    parkAmount: Number(data.parkingSpaces),
    dispatchAmount: data.dispatch_amount,
    chargingStations:  Number(data.chargingStations),
    agv: data.agv,
    totalProductCapacity: data.totalProductCapacity,
    singleProductCapacity: data.singleProductCapacity,
    warehouseWidth:data.warehouseWidth,
    warehouseLength:data.warehouseLength,
    goodsWidth:data.goodsWidth,
    goodsLength:data.goodsWidth
  };

  adjustParamsDialog.value.openDialog(initialValues,index);
};
//调整参数
const handleUpdateImage = async (payload:any) => {
  const { pngData, imgIndex, statsData,gridFile,mapId,agv, totalProductCapacity,singleProductCapacity } = payload;
  const gridData = await gridFile.async('blob');

  // 把 pngData 构造成一个文件并上传
  const pngBlob = new Blob([pngData], { type: 'image/png' });
  const pngFileForUpload = new File([pngBlob], 't-model.png', { type: 'image/png' });
  // 上传图片
  const res = await uploadCADFiles(pngFileForUpload);

  const uploadedImageUrl = res.data.result.url;

  const imageUrl = URL.createObjectURL(pngData);
  if (mapCards.value[imgIndex]) {
    mapCards.value[imgIndex].imageSrc = imageUrl;
    mapCards.value[imgIndex].gridBlob = gridData;
    mapCards.value[imgIndex].statsData = {
      totalBlocks: statsData.occupy_area,
      fingerCount: statsData.finger_amount,
      gridCount: statsData.chute_amount,
      chargingStations: statsData.charge_pile_amount,
      chargingParkingSpaces: statsData.charge_pile_amount,
      parkingSpaces: statsData.parking_count,
      queueAreas: statsData.queue_area_count,
      operationAreas: statsData.running_area_count,
      dispatch_amount: statsData.dispatch_amount,
      generationMethod: 'Auto',
      agv:agv,
      totalProductCapacity:totalProductCapacity,
      singleProductCapacity:singleProductCapacity,
      warehouseWidth:statsData.warehouse_width,
      warehouseLength:statsData.warehouse_length,
      goodsWidth:statsData.goods_width,
      goodsLength:statsData.goods_length
    };

    await updateProjectMap(mapId,uploadedImageUrl)
    console.log('Updated image URL:', imageUrl);
  } else {
    console.warn(`Card ${imgIndex} not existing`);
  }
};

const deleteMap = async (index:number,projectMapDetailId: any) => {
  //调用后端删除
  const response  = await deleteProjectMapDetail({ id: projectMapDetailId });
  console.log("response",response);
  mapCards.value.splice(index, 1);
  tableRef.value?.handleList(); // 刷新表格数据
}


//文件上传逻辑
const startUpload = async () => {
  // 检查是否有已存在的地图卡片
  if (mapCards.value && mapCards.value.length > 0) {
    try {
      // 弹出确认框询问用户是否使用初始图grid文件
      await ElMessageBox.confirm(
          t('message.pageConfiguration.whetherInitialGridFile'),
          t('message.pageConfiguration.uploadConfirmation'),
          {
            confirmButtonText: t('message.pageConfiguration.yes'),
            cancelButtonText: t('message.pageConfiguration.no'),
            type: 'info',
          }
      );

      // 用户选择"是"，使用第一个mapCard的grid文件
      const firstCard = mapCards.value[0];
      if (firstCard && firstCard.gridBlob) {
        // 创建一个新的File对象基于现有的gridBlob
        const file = new File([firstCard.gridBlob], 'test.grid', {
          type: 'application/octet-stream',
        });

        // 创建一个虚拟的事件对象来调用handleFileChange
        const fakeEvent = {
          target: {
            files: [file]
          }
        } as unknown as Event;

        // 调用处理文件的函数
        handleFileChange(fakeEvent);
      } else {
        ElMessage.error(t('message.pageConfiguration.initialGridFileNotFound'));
      }
    } catch (error) {
      // 用户选择"否"，触发文件选择框
      fileInput.value?.click();
    }
  } else {
    // 没有现成的地图卡片，直接触发文件选择框
    fileInput.value?.click();
  }
}

const handleFileChange = async (event: Event) =>{
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  console.log(file);

  if (file) {

    // 校验文件扩展名是否为 .grid
    const fileName = file.name;
    const fileExtension = fileName.split('.').pop()?.toLowerCase();

    if (fileExtension !== 'grid') {
      ElMessage.error('Only file with format xx.grid can be uploaded');
      return; // 如果不是 .grid 文件，阻止后续操作
    }


    isUploading.value = true;

    try {
      const response = await generateTModel(file,String(projectId.value));
      console.log("response",String(projectId.value));
      console.log("response",response);
      // 1. 取出 base64 文件内容 和 额外数据字符串
      const { fileContent, additionalData } = response.data.result;

      // 2. 解析 additionalData 成对象
      const { projectMapDetailId, mapData } = extractAdditionalData(additionalData);

      console.log('projectMapDetailId:', projectMapDetailId);
      console.log('mapData:', mapData);

      // 3. 使用 jszip 解析 ZIP 文件（Base64）
      const zip = new JSZip();
      await zip.loadAsync(fileContent, { base64: true });

      const pngFile = zip.file('t-model.png');
      const gridFile = zip.file('test.grid');

      if  (pngFile && gridFile && mapData) {
        const map: MapData = mapData

        const pngData = await pngFile.async('blob');
        const gridData = await gridFile.async('blob');



        const pngBlob = new Blob([pngData], { type: 'image/png' });
        const pngFileForUpload = new File([pngBlob], 't-model.png', { type: 'image/png' });

        // 上传图片
        const res = await uploadCADFiles(pngFileForUpload);
        //获取传回来的文件地址
        const uploadedImageUrl = res.data.result.url;
        console.log('ccURL2');
        console.log(uploadedImageUrl);

        // 获取项目详情
        const projectDetail = await detailProject({ Id: projectId.value });

        // 构建更新参数
        const updateData = {
          id: projectId.value,
          cadFiles: uploadedImageUrl
        };

        // 调用更新接口
        const updateResult = await updateProject(updateData);

        const resMap = await updateProjectMap(projectMapDetailId,uploadedImageUrl)

        //修改小黄人数量
        await updaagv(projectMapDetailId, agvCount.value )
        console.log('Update result:', resMap);

        await sumDateMap(projectMapDetailId,projectId.value)




        mapCards.value.push({
          imageSrc: URL.createObjectURL(pngData),
          gridBlob: gridData,
          projectMapDetailId: projectMapDetailId,
          statsData: {
            totalBlocks: map.occupy_area,
            fingerCount: map.finger_amount,
            queueAreas: map.queue_area_count,
            operationAreas: map.running_area_count,
            chargingStations: map.charge_pile_amount,
            dispatch_amount: map.dispatch_amount,
            chargingParkingSpaces: map.charge_pile_amount,
            parkingSpaces: map.parking_count,
            gridCount: map.chute_amount,
            generationMethod: 'Manual',
            agv:agvCount.value,
            totalProductCapacity: map.totalProductCapacity,
            singleProductCapacity: map.singleProductCapacity,
            warehouseWidth:map.warehouse_width,
            warehouseLength:map.warehouse_length,
            goodsWidth:map.goods_width,
            goodsLength:map.goods_length
          },
          generationTime: new Date().toLocaleString()
        });
        //刷新表格
        tableRef.value?.handleList(); // 刷新表格数据
      }
    } catch (error) {
      ElMessage.error('Upload error');
      console.error('Upload error::', error);
    } finally {
      isUploading.value = false;
    }
  }
}
function extractAdditionalData(additionalDataStr:any) {
  const result = {
    projectMapDetailId: null,
    mapData: null
  };

  // 提取 ProjectMapDetailId
  const idMatch = additionalDataStr.match(/ProjectMapDetailId:\s*(\d+)/);
  if (idMatch) {
    result.projectMapDetailId = idMatch[1];
  }

  // 提取 MapData 字符串并解析为 JSON
  const mapDataMatch = additionalDataStr.match(/{.*}/);
  if (mapDataMatch) {
    try {
      result.mapData = JSON.parse(mapDataMatch[0]);
    } catch (e) {
      console.error('MapData JSON parse error', e);
    }
  }

  return result;
}

//生成方案
const generateDocument = async (projectMapDetailId: any) => {
  try {
    const res = await generateScheme(Number(projectId.value),projectMapDetailId);
    console.log("File", res);

    // 处理文件下载
    handleFileDownload(res);
  } catch (error) {
    ElMessage.error('Get plan error');
    console.error('Get plan error:', error);
  }
};

//转为CAD图片
const gencad = async (projectMapDetailId: any) => {

    //1.调python接口传grid文件2.接受python返回的文件调后端接口保存到数据库和服务器的地址中
   // const res = await generateScheme(Number(projectId.value),projectMapDetailId);
    //console.log("File", res);




console.log(projectMapDetailId);
    let ccc = await getMapListByNo({ projectNo: Number(projectId.value) });
      //const res = await seleProjectMapDetail(Number(projectId.value),projectMapDetailId);
console.log(ccc.data.result);
console.log('ccc');






 try {
    const res = await generateScheme(Number(projectId.value),projectMapDetailId);

    console.log("File", res);

    // 处理文件下载
    handleFileDownload(res);
  } catch (error) {
    ElMessage.error('Get plan error');
    console.error('Get plan error:', error);
  }








};


const generateDocumentc = async (projectId: any) => {
  try {

    console.log(projectId);
    console.log('123');
    const res = await generateScheme(projectId.projectNo,projectId.id);
    console.log("File", res);

    // 处理文件下载
    handleFileDownload(res);
  } catch (error) {
    ElMessage.error('Get plan error');
    console.error('Get plan error:', error);
  }
};
//下载pdf
const  getpdf = async (id:any)  => {
  console.log(id);
 ElMessageBox.alert(
    'PDF is being generated. Please wait!',
    'system prompt',
    {
      confirmButtonText: 'YES',
      type: 'info',
    }
  )
 const resPdf = await downloadProjectFile(projectId.value,id)

  console.log("resPdf",resPdf);
  const url = window.URL.createObjectURL(new Blob([resPdf.data]));
  const a = document.createElement('a');
  a.href = url;
  a.download = 'Quote.pdf'; // 设置下载文件名
  document.body.appendChild(a);
  a.click();
  a.remove();
  window.URL.revokeObjectURL(url); // 清理内存

}
  //转为cad
const  getADDCAD = async (file: any,id:any)  => {

 ElMessageBox.alert(
    'CAD is being generated. Please wait!',
    'system prompt',
    {
      confirmButtonText: 'YES',
      type: 'info',
    }
  )
  const csr =  await addCADFiles(file,id);
  const res = csr.data.result
  const base64Data = res.fileContent;

  const zip = new JSZip();
  await zip.loadAsync(base64Data, { base64: true });

  const pngFile = zip.file('cad.png');
  const dxfFile = zip.file('output.dxf');


  if (pngFile && dxfFile) {
    // 异步读取文件内容
    const pngData = await pngFile.async('blob');
    const dxfData = await dxfFile.async('string'); // DXF 通常是文本文件

    // 创建 PNG Blob（用于图片）
    const pngBlob = new Blob([pngData], { type: 'image/png' });

    // 创建 DXF Blob（用于文本文件）
    const dxfBlob = new Blob([dxfData], { type: 'application/dxf' }); // 设置正确的 MIME 类型

    // 创建下载链接并触发下载（PNG）
    const pngUrl = URL.createObjectURL(pngBlob);
    const pngLink = document.createElement('a');
    pngLink.href = pngUrl;
    pngLink.download = 'CAD.png'; // 设置下载文件名
    pngLink.click();
    URL.revokeObjectURL(pngUrl); // 清理内存

    // 创建下载链接并触发下载（DXF）
    const dxfUrl = URL.createObjectURL(dxfBlob);
    const dxfLink = document.createElement('a');
    dxfLink.href = dxfUrl;
    dxfLink.download = 'CAD.dxf'; // 设置下载文件名
    dxfLink.click();
    URL.revokeObjectURL(dxfUrl); // 清理内存
  } else {
    console.error('No download file available');
  }
}

const getCAD = async (row: any) => {
 ElMessageBox.alert(
    'CAD is being generated. Please wait!',
    'system prompt',
    {
      confirmButtonText: 'YES',
      type: 'info',
    }
  )
  if (row.zipFile && row.id){
    const zipData = row.zipFile;



    const zip = new JSZip();
    await zip.loadAsync(zipData, { base64: true });

    const gridFile = zip.file('test.grid');

    if (gridFile) {
      const gridData = await gridFile.async('blob');

      // 创建 File 对象
      const fileForUpload = new File([gridData], 'test.grid', { type: 'application/octet-stream' });

      const csr =  await addCADFiles(fileForUpload,row.id);
      const res = csr.data.result
      const base64Data = res.fileContent;

      const newZip = new JSZip();
      await newZip.loadAsync(base64Data, { base64: true });

      const pngFile = newZip.file('cad.png');
      const dxfFile = newZip.file('output.dxf');


      if (pngFile && dxfFile) {
         ElMessage.success('Downloading, please wait!');
        // 异步读取文件内容
        const pngData = await pngFile.async('blob');
        const dxfData = await dxfFile.async('string'); // DXF 通常是文本文件

        // 创建 PNG Blob（用于图片）
        const pngBlob = new Blob([pngData], { type: 'image/png' });

        // 创建 DXF Blob（用于文本文件）
        const dxfBlob = new Blob([dxfData], { type: 'application/dxf' }); // 设置正确的 MIME 类型


        // 创建下载链接并触发下载（PNG）
        const pngUrl = URL.createObjectURL(pngBlob);
        const pngLink = document.createElement('a');
        pngLink.href = pngUrl;
        pngLink.download = 'cad.png'; // 设置下载文件名
        pngLink.click();
        URL.revokeObjectURL(pngUrl); // 清理内存

        // 创建下载链接并触发下载（DXF）
        const dxfUrl = URL.createObjectURL(dxfBlob);
        const dxfLink = document.createElement('a');
        dxfLink.href = dxfUrl;
        dxfLink.download = 'output.dxf'; // 设置下载文件名
        dxfLink.click();
        URL.revokeObjectURL(dxfUrl); // 清理内存

         ElMessageBox.alert(
    'CAD has been generated. Please check your default download folder.',
    'system prompt',
    {
      confirmButtonText: 'YES',
      type: 'info',
    }
  )
      } else {
        console.error('No download file available');
      }
    }
  }

};


const handleFileDownload = (response: any) => {
  // 获取文件名
  const contentDisposition = response.headers['content-disposition'];
  let fileName = 'Final Plan.pptx'; // 默认文件名

  if (contentDisposition) {
    // 注意这里是 contentDisposition，不是 content-Disposition
    const nameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);

    if (nameMatch && nameMatch[1]) {
      fileName = decodeURIComponent(nameMatch[1].replace(/['"]/g, ''));
    }
  }



  // 创建一个 Blob 对象
  const blob = new Blob([response.data], {
    type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
  });

  // 创建下载链接并触发下载
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = fileName;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(link.href);
};


//base64转blob
function base64ToBlob(base64: string, mimeType: string = 'application/octet-stream'): Blob {
  const byteString = atob(base64);
  const arrayBuffer = new ArrayBuffer(byteString.length);
  const int8Array = new Uint8Array(arrayBuffer);

  for (let i = 0; i < byteString.length; i++) {
    int8Array[i] = byteString.charCodeAt(i);
  }

  return new Blob([int8Array], { type: mimeType });
}





































const uploadCADFilesHandle = async (options: UploadRequestOptions) => {
	const res = await uploadCADFiles(options);
	ruleForm.value.cADFiles = res.data.result?.url;
};


// 页面加载时
onMounted(async () => {

});


//将属性或者函数暴露给父组件
defineExpose({ openDialog  });


</script>
<style>
.el-dialog.is-draggable .el-dialog__header {
	border-radius: 10px 10px 0px 0px;
}
.cards-container {
  display: flex;
  overflow-x: auto;
  padding: 10px;
}
.map-detail-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.generation-info {
  margin-bottom: 10px;
}

.map-area {
  border: 1px solid #ccc;
  margin-bottom: 20px;
}

.map-background {
  position: relative;
  overflow: auto; /* 添加滚动条 */
  padding-top: 46.25%; /* 默认 16:9 宽高比 */
  background-color: #f0f0f0;
}


.map-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain; /* 或 cover 根据需求 */
}

.stats-info {
  margin-bottom: 20px;
  display: block;
}


.bottom-buttons {
  text-align: right;
}

.cards-container {
  display: flex;
  overflow-x: auto;
  padding: 10px;
}

.box-card {
  min-width: 900px;
  margin-right: 20px;
}

.upload-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 600px;
  margin-right: 20px;
  height: 500px;
  border: 2px dashed #ccc;
  border-radius: 8px;
  background-color: #fafafa;
  position: relative; /* 相对定位 */
}

.cross-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100px;
  height: 100px;
}

.cross-icon::before,
.cross-icon::after {
  content: '';
  position: absolute;
  background-color: #ccc;
}

.cross-icon::before {
  width: 100%;
  height: 2px;
  top: 50%;
  left: 0;
}

.cross-icon::after {
  width: 2px;
  height: 100%;
  top: 0;
  left: 50%;
}

.upload-button {
  position: absolute;
  bottom: 20px;
  right: 20px;
}
</style>
